{#
 # ---------------------------------------------------------------------
 #
 # GLPI - Gestionnaire Libre de Parc Informatique
 #
 # http://glpi-project.org
 #
 # @copyright 2015-2025 Teclib' and contributors.
 # @licence   https://www.gnu.org/licenses/gpl-3.0.html
 #
 # ---------------------------------------------------------------------
 #
 # LICENSE
 #
 # This file is part of GLPI.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #
 # ---------------------------------------------------------------------
 #}

{% set load_actors = params['load_actors'] ?? true %}
{% set actors = load_actors ? item.getActorsForType(actortypeint, params) : [] %}

{% set required = false %}
{% if itiltemplate.isMandatoryField('_users_id_' ~ actortype) or itiltemplate.isMandatoryField('_groups_id_' ~ actortype) or (actortype == 'assign' and itiltemplate.isMandatoryField('_suppliers_id_' ~ actortype)) %}
   {% set required = true %}
{% endif %}

{% set is_actor_hidden = false %}
{% if itiltemplate.isHiddenField('_users_id_' ~ actortype) and itiltemplate.isHiddenField('_groups_id_' ~ actortype) and (actortype != 'assign' or itiltemplate.isHiddenField('_suppliers_id_' ~ actortype)) %}
   {% set is_actor_hidden = true %}
{% endif %}

{% set onchange = '' %}
{% set allow_auto_submit = allow_auto_submit ?? true %}
{% if allow_auto_submit and item.isNewItem() and actortype == "requester" %}
   {% set onchange = 'e.target.form.submit();' %}
{% endif %}

{% if not is_actor_hidden %}
   <select class="form-select" multiple="true" id="actor_{{ rand }}" data-actor-type="{{ actortype }}"
        {{ required ? 'required' : '' }}>
   {% for actor in actors %}
      {% set unique_id = "user_opt_" ~ actortype ~ actor.itemtype ~ actor.items_id %}
      {% set actor_use_notification = actor['use_notification'] ?? false %}
      <option selected="true" value="{{ actor['itemtype'] ~ '_' ~ actor['items_id'] }}"
            data-itemtype="{{ actor['itemtype'] }}" data-items-id="{{ actor['items_id'] }}"
            data-use-notification="{{ actor_use_notification ? 1 : 0 }}"
            data-default-email="{{ actor['default_email'] ?? '' }}"
            data-alternative-email="{{ actor['alternative_email'] ?? '' }}"
            {% if (actor['itemtype'] == 'User' and itiltemplate.isHiddenField('_users_id_' ~ actortype)) or (actor['itemtype'] == 'Group' and itiltemplate.isHiddenField('_groups_id_' ~ actortype)) %}
               disabled="disabled" style="display: none;"
            {% endif %}
            data-text="{{ actor['text'] }}" data-title="{{ actor['title'] }}" data-glpi-popover-source="content{{ unique_id }}">
         {{ actor['title'] }}
      </option>
   {% endfor %}
   </select>

   {% if not item.isNewItem() and not (params['template_preview'] ?? false) and canassigntome %}
      {{ include('components/itilobject/actors/assign_to_me.html.twig') }}
   {% endif %}

    {#
        Prevent WAF (Web Application Firewall) from triggering on item.fields['content']

        The WAF rule (signature ID 010000092) is triggered due to the presence of HTML-encoded content
        in the 'content' field, which is falsely identified as a potential XSS injection.
        This key is removed from the AJAX payload to avoid false positives.

        Reference: https://github.com/glpi-project/glpi/pull/10300
    #}
    {% set safe_item_fields = item.fields|filter((value, key) => key != 'content') %}
    <script type="module" defer>
        const actorytype = '{{ actortype }}';

        // function to display an option in the list or the selected input
        function genericTemplate(option = {}, is_selection = false) {
            const element   = $(option.element);
            const itemtype  = element.data('itemtype') ?? option.itemtype;
            const items_id  = element.data('items-id') ?? option.items_id;
            let text        = escapeMarkupText(element.data('text') ?? option.text ?? '');
            const title     = escapeMarkupText(element.data('title') ?? option.title ?? '');
            const use_notif = element.data('use-notification') ?? option.use_notification ?? 1;
            const alt_email = element.data('alternative-email') ?? option.alternative_email ?? '';

            let icon = "";
            let fk   = "";
            switch (itemtype) {
                case "User":
                    if (items_id == 0) {
                        text = alt_email;
                        icon = `<i class="ti ti-mail mx-1" title="{{ __('Direct email') }}"></i>`;
                    } else {
                        icon = `<i class="ti ti-user mx-1" title="{{ 'User'|itemtype_name }}"></i>`;
                    }
                    if ("{{ actortype }}" == "assign") {
                        fk = "users_id_assign";
                    } else if ("{{ actortype }}" == "requester") {
                        fk = "users_id_requester";
                    } else if ("{{ actortype }}" == "observer") {
                        fk = "users_id_observer";
                    }
                    break;
                case "Group":
                    icon = `<i class="ti ti-users mx-1" title="{{ 'Group'|itemtype_name }}"></i>`;
                    if ("{{ actortype }}" == "assign") {
                        fk = "groups_id_assign";
                    } else if ("{{ actortype }}" == "requester") {
                        fk = "groups_id_requester";
                    } else if ("{{ actortype }}" == "observer") {
                        fk = "groups_id_observer";
                    }
                    break;
                case "Supplier":
                    icon = `<i class="ti ti-package mx-1" title="{{ 'Supplier'|itemtype_name }}"></i>`;
                    fk   = "suppliers_id_assign";
                    break;
            }

            let actions = "";
            {% if canupdate %}
            if (['User', 'Supplier', 'Email'].includes(itemtype)
                && is_selection) {
                const icon_class = use_notif ? "ti-bell-filled" : "ti-bell";
                actions = `
                    <button class="btn btn-sm btn-ghost-secondary edit-notify-user"
                              data-bs-toggle="tooltip" data-bs-placement="top"
                              title="{{ __('Email followup') }}"
                              type="button">
                        <i class="ti ${icon_class} notify-icon"></i>
                    </button>`;
            }
            {% endif %}

            // manage specific display for tree data (like groups)
            let indent = "";
            if (!is_selection && "level" in option && option.level > 1) {
                for (let index = 1; index < option.level; index++) {
                    indent = "&nbsp;&nbsp;&nbsp;"+indent;
                }
                indent = indent+"&raquo;";
            }

            // prepare html for option element
            text = (is_selection && itemtype == "Group") ? title : text;
            const option_text    = `<span class="actor_text">${text}</span>`;
            const option_element = $(`<span class="actor_entry" data-itemtype="${itemtype}" data-items-id="${items_id}" data-actortype="${actorytype}">${indent}${icon}${option_text}${actions}</span>`);

            if (is_selection && itemtype == "User") {
                const unique_id = "user_opt_" + actor_select.attr('data-actor-type') + "User" + items_id;
                $.ajax({
                    url: '{{ path('/ajax/comments.php') }}',
                    type: 'POST',
                    data: {
                        'itemtype': 'User',
                        'value': items_id,
                    }
                }).then((result) => {
                    if (result) {
                        actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                        option_element.attr('data-glpi-popover-source', `content${unique_id}`);
                    }
                });
            }

            if (is_selection && itemtype == "Group") {
                const unique_id = "group_opt_" + actor_select.attr('data-actor-type') + "Group" + items_id;
                $.ajax({
                    url: '{{ path('/ajax/comments.php') }}',
                    type: 'POST',
                    data: {
                        'itemtype': 'Group',
                        'value': items_id,
                    }
                }).then((result) => {
                    if (result) {
                        actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                        option_element.attr('data-glpi-popover-source', `content${unique_id}`);
                    }
                });
            }

            if (is_selection && itemtype == "Supplier") {
                const unique_id = "supplier_opt_" + actor_select.attr('data-actor-type') + "Supplier" + items_id;
                $.ajax({
                    url: '{{ path('/ajax/comments.php') }}',
                    type: 'POST',
                    data: {
                        'itemtype': 'Supplier',
                        'value': items_id,
                    }
                }).then((result) => {
                    if (result) {
                        actor_select.parent().append('<' + `div id="content${unique_id}" style="display: none;">` + result + '<' + '/div>');
                        option_element.attr('data-glpi-popover-source', `content${unique_id}`);
                    }
                });
            }

            // manage ticket information (number of assigned ticket for an actor)
            if (is_selection && itemtype != "Email") {
                let label = '';
                if ("{{ actortype }}" == "assign") {
                    label = "{{ __('Number of tickets already assigned') }}";
                } else if ("{{ actortype }}" == "requester") {
                    label = "{{ __('Number of tickets as requester') }}";
                }
                const existing_element = $(`
                    <span class="assign_infos ms-1" title="${label}"
                        data-bs-toggle="tooltip" data-bs-placement="top"
                        data-id="${items_id}" data-fk="${fk}">
                        <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                    </span>
                `);
                option_element.append(existing_element);

                $.get("{{ path('/ajax/actorinformation.php') }}", {
                    [fk]: items_id,
                    only_number: true,
                }).done((number) => {
                    const badge = number.length > 0 ? `<span class="badge bg-secondary-lt">${number}</span>` : '';
                    existing_element.html(badge);
                });
            }

            return option_element;
        }

        const select2_width = "{{ canassigntome ? 'calc(100% - 30px)' : '100%' }}";

        const actor_select = $("#actor_{{ rand }}");
        actor_select.select2({
            tags: true,
            width: select2_width,
            tokenSeparators: [',', ' '],
            containerCssClass: 'actor-field',
            templateSelection: (option) => genericTemplate(option, true),
            templateResult: (option) => genericTemplate(option, false),
            disabled: {{ canupdate ? 'false' : 'true' }},
            createTag: (params) => {
                const term = $.trim(params.term);

                if (term === '') {
                    return null;
                }

                // Don't offset to create a tag if it's not an email
                if (!new RegExp(/^[\w-\.]+@([\w-]+\.)+[\w-]{2,63}$/).test(term)) {
                    // Return null to disable tag creation
                    return null;
                }

                return {
                    id: term,
                    text: term,
                    itemtype: "User",
                    items_id: 0,
                    use_notification: 1,
                    alternative_email: term,
                }
            },
            ajax: {
                url: '{{ path('/ajax/actors.php') }}',
                datatype: 'json',
                type: 'POST',
                delay:250,
                data: (params) => {
                    const is_new_item = {{ item.isNewItem() ? "true" : "false" }};
                    return {
                        action: 'getActors',
                        actortype: actorytype,
                        users_right: '{{ users_right ?? 'all' }}',
                        entity_restrict: (window.actors.requester.length === 0 && is_new_item) ? -1 : {{ entities_id }},
                        searchText: params.term,
                        _idor_token: '{{ idor_token(item.getType(), {'users_right': users_right ?? 'all'}) }}',
                        itiltemplate_class: '{{ itiltemplate.getType() }}',
                        itiltemplates_id: {{ itiltemplate.fields['id'] ?? 0 }},
                        itemtype: '{{ item.getType() }}',
                        items_id: {{ item.isNewItem() ? -1 : item.fields['id'] }},
                        item: {{ safe_item_fields|json_encode|raw }},
                        returned_itemtypes: {{ (returned_itemtypes ?? ['User', 'Group', 'Supplier'])|json_encode()|raw }},
                        page: params.page || 1
                    };
                },
            }
        }).on('select2:open', () => {
            // Close popovers
            $('.popover').popover('hide');
        });

        actor_select.parent().popover({
            selector: '[data-glpi-popover-source]',
            container: actor_select.parent(),
            html: true,
            sanitize: false,
            trigger: 'hover',
            delay: {
                hide: 300
            },
            content: (el) => {
                // Close other popovers
                $('.popover').popover('hide');
                return $('#' + $(el).attr('data-glpi-popover-source')).html();
            }
        }).on('hide.bs.popover', () => {
            // prevent closing popover when user card is hover
            if ($('.user-info-card:hover').length > 0) {
                return false;
            }
            // prevent closing popover when group card is hover
            if ($('.group-info-card:hover').length > 0) {
                return false;
            }
            // prevent closing popover when group card is hover
            if ($('.supplier-info-card:hover').length > 0) {
                return false;
            }
        });

        // when the mouse leave the user card in the popover, close it
        $(document).on('mouseleave', '.user-info-card', () => {
            setTimeout(() => {
                $('.popover').popover('hide');
            }, 300);
        });

        // when the mouse leave the group card in the popover, close it
        $(document).on('mouseleave', '.group-info-card', () => {
            setTimeout(() => {
                $('.popover').popover('hide');
            }, 300);
        });

        // when the mouse leave the supplier card in the popover, close it
        $(document).on('mouseleave', '.supplier-info-card', () => {
            setTimeout(() => {
                $('.popover').popover('hide');
            }, 300);
        });

        // manage actors change
        function updateActors() {
            const data = $("#actor_{{ rand }}").select2('data');

            const new_actors = [];
            data.forEach((selection) => {
                const element = $(selection.element);

                let itemtype  = selection.itemtype ?? element.data('itemtype');
                const items_id  = selection.items_id ?? element.data('items-id');
                let use_notif = selection.use_notification  ?? element.data('use-notification')  ?? false;
                const def_email = selection.default_email ?? element.data('default-email') ?? '';
                let alt_email = selection.alternative_email ?? element.data('alternative-email') ?? '';

                if (itemtype == "Email") {
                    itemtype  = "User";
                    use_notif = true;
                    alt_email = selection.id;
                }

                new_actors.push({
                    itemtype: itemtype,
                    items_id: items_id,
                    use_notification: use_notif,
                    default_email: def_email,
                    alternative_email: alt_email,
                });
            });

            window.actors[actorytype] = new_actors;

            saveActorsToDom();
        }

        $("#actor_{{ rand }}").on('select2:select', (e) => {
            updateActors();
            {{ onchange }}
        });
        $("#actor_{{ rand }}").on('select2:unselect', (e) => {
            updateActors();
            {{ onchange }}
        });

        // intercept event for edit notification button
        document.addEventListener('click', event => {
            if (event.target.closest("#actor_{{ rand }} + .select2 .edit-notify-user")) {
                return openNotifyModal(event);
            }
            // if a click on assign info is detected prevent opening of select2
            if (event.target.closest("#actor_{{ rand }} + .select2 .assign_infos")) {
                event.stopPropagation();
            }
        }, {capture: true})
        document.addEventListener('keydown', event => {
            if (event.target.closest("#actor_{{ rand }} + .select2 .edit-notify-user")
                && event.key == "Enter") {
                return openNotifyModal(event);
            }
        }, {capture: true})

        {% if itiltemplate.isHiddenField('_users_id_' ~ actortype) %}
        $(".actor_entry[data-itemtype=\"User\"][data-actortype=\"{{ actortype }}\"]").parent().css("display", "none");
        {% endif %}
        {% if itiltemplate.isHiddenField('_groups_id_' ~ actortype) %}
        $(".actor_entry[data-itemtype=\"Group\"][data-actortype=\"{{ actortype }}\"]").parent().css("display", "none");
        {% endif %}
    </script>
{% endif %}
